package com.example.beat_x3.Client;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;

import androidx.annotation.NonNull;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;

import Entity.Inf;
import Entity.NetImages;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;


public class LoadImages {
    public static String Path;
    public static String PLACE_SRC;
    public static String EQUIPMENT_SRC;
    public static final int PLACE_IMAGES = 0;
    public static final int EQUIPMENT_IMAGES = 1;
    @SuppressLint("StaticFieldLeak")
    public static Context context;

    public static void setContext(Context context) {
        LoadImages.context = context;
        LoadImages.Path = context.getFilesDir().getAbsolutePath();
        PLACE_SRC = Path + "/BEATX3_PLACE_IMAGE";
        EQUIPMENT_SRC = Path + "/BEATX3_EQUIPMENT_IMAGE";
    }

    public static HashMap<String, Integer> init(int type) {
        File folder = new File(type == 0 ? PLACE_SRC : EQUIPMENT_SRC);
        if (!folder.exists()) folder.mkdirs();
        HashMap<String, Integer> maps = getResult(type, folder, type == 0 ? PLACE_SRC : EQUIPMENT_SRC);
        checkImagesInFolder(folder, maps);
        return maps;
    }

    private static void checkImagesInFolder(File folder, HashMap<String, Integer> maps) {
        if (maps == null) return;
        File[] files = folder.listFiles();
        if (files != null) {
            for (File file : files) {
                if (!maps.containsKey(file.getName())) file.delete();
            }
        }
    }

    private static HashMap<String, Integer> getResult(int type, File folder, String path) {
        OutputStream out = null;
        ObjectInputStream in = null;
        NetImages images = null;
        try {
            Socket socket = new Socket(Inf.ip, 9998);
            socket.setSoTimeout(5000);
            out = new BufferedOutputStream(socket.getOutputStream());
            in = new ObjectInputStream(socket.getInputStream());
            out.write(("queryImages\\" + type).getBytes());
            out.flush();
            socket.shutdownOutput();
            images = (NetImages) in.readObject();
            System.out.println("end of connection");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                out.close();
                in.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        if (images == null) return null;
        HashMap<String, Integer> maps = new HashMap<>();
        HashMap<String, Integer> photos = new HashMap<>();
        for (File file : folder.listFiles()) {
            photos.put(file.getName(), 1);
        }

        for (String x : images.images) {
            if (!photos.containsKey(x)) downloadImages(path, x);
            maps.put(x, 1);
        }
        return maps;
    }

    public static void saveImageToFile(InputStream inputStream, String localSrc, String imageSrc) throws IOException {
        try (OutputStream outputStream = Files.newOutputStream(Paths.get(localSrc, imageSrc))) {
            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
            outputStream.flush();
        }
    }

    public static String saveBitmapToInternalStorage(Bitmap bitmap, String imageSrc) {
        OutputStream outputStream = null;
        File f = new File(LoadImages.EQUIPMENT_SRC, imageSrc);
        try {
            outputStream = Files.newOutputStream(f.toPath());
            bitmap.compress(Bitmap.CompressFormat.PNG, 50, outputStream);
            outputStream.flush();
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return f.getAbsolutePath();
    }

    public static void downloadImages(String localsrc, String imageSrc) {
        OkHttpClient client = new OkHttpClient();
        File file = new File(localsrc, imageSrc);
        Request request = new Request.Builder()
                .url("http://" + Inf.ip + ":8080/download/" + imageSrc)
                .get()
                .build();
        client.newBuilder().readTimeout(4000, TimeUnit.MILLISECONDS).build().newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NonNull Call call, @NonNull IOException e) {
                System.out.println("NETWORK ERROR");
            }

            @Override
            public void onResponse(@NonNull Call call, @NonNull okhttp3.Response response) throws IOException {
                if (response.isSuccessful() && response.body() != null) {
                    InputStream inputStream = response.body().byteStream();
                    saveImageToFile(inputStream, localsrc, imageSrc);
                    if (localsrc == PLACE_SRC) Inf.place_images.put(imageSrc, 1);
                    else Inf.equipment_images.put(imageSrc, 1);
                }
            }
        });
    }

    public static void upLoadImage(String imageSrc, int type) {
        OkHttpClient client = new OkHttpClient();
        File file = new File(imageSrc);
        MultipartBody.Builder requestBody = new MultipartBody.Builder().setType(MultipartBody.FORM);
        RequestBody fileBody = RequestBody.create(MediaType.parse("image/*"), file);
        requestBody.addFormDataPart("file", file.getName(), fileBody);
        Request request = new Request.Builder()
                .url("http://" + Inf.ip + ":8080/upload")
                .post(requestBody.build())
                .build();
        client.newBuilder().readTimeout(4000, TimeUnit.MILLISECONDS).build().newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(@NonNull Call call, @NonNull IOException e) {
            }

            @Override
            public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
                if (response.isSuccessful())
                    Inf.equipment_images.put(imageSrc, 1);
            }
        });
    }
}

